//
// Created by Craft on 2024/12/24.
//

#include "beamquality_2d_view_settings.h"
#include "ui_BeamQuality_2D_View_Settings.h"

BeamQuality_2D_View_Settings::BeamQuality_2D_View_Settings(QWidget *parent) :
        QDockWidget(parent), ui(new Ui::BeamQuality_2D_View_Settings) {
    ui->setupUi(this);
    setWindowTitle("BeamQuality Measurement:2D-View");
    setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
    initView();
    connect(ui->rBtn_Rectangle, &QRadioButton::clicked, this, [=] () {
        if(changeUnable) return;
        emit setAOIShape(1);
    });
    connect(ui->rBtn_Ellipse, &QRadioButton::clicked, this, [=] () {
        if(changeUnable) return;
        emit setAOIShape(0);
    });
    connect(ui->dSBox_X, &QDoubleSpinBox::valueChanged, this, [=] () {
        if(changeUnable) return;
        auto dPosX = ui->dSBox_X->value();
        auto dPosY = ui->dSBox_Y->value();
        emit setPosition_px(dPosX, dPosY);
    });
    connect(ui->dSBox_Y, &QDoubleSpinBox::valueChanged, this, [=] () {
        if(changeUnable) return;
        auto dPosX = ui->dSBox_X->value();
        auto dPosY = ui->dSBox_Y->value();
        emit setPosition_px(dPosX, dPosY);
    });
    connect(ui->dSBox_D, &QDoubleSpinBox::valueChanged, this, [=] () {
        if(changeUnable) return;
        auto dMajor = ui->dSBox_D->value();
        auto dMinor = ui->dSBox_d->value();
        if(dMajor < dMinor) {
            ui->dSBox_D->setValue(dMinor);
            ui->dSBox_d->setValue(dMajor);
            double a = dMajor;
            dMajor = dMinor;
            dMinor = a;
        }
        auto dPhi = ui->dSBox_Phi->value();
        emit setAOISize(dMajor, dMinor, dPhi);
    });
    connect(ui->dSBox_d, &QDoubleSpinBox::valueChanged, this, [=] () {
        if(changeUnable) return;
        auto dMajor = ui->dSBox_D->value();
        auto dMinor = ui->dSBox_d->value();
        if(dMajor < dMinor) {
            ui->dSBox_D->setValue(dMinor);
            ui->dSBox_d->setValue(dMajor);
            double a = dMajor;
            dMajor = dMinor;
            dMinor = a;
        }
        auto dPhi = ui->dSBox_Phi->value();
        emit setAOISize(dMajor, dMinor, dPhi);
    });
    connect(ui->cBox_ShowAxes, &QCheckBox::clicked, this, [=] () {

    });
    connect(ui->cBox_Image_X, &QComboBox::currentIndexChanged, this, [=] () {
        auto index = ui->cBox_Image_X->currentIndex();
        emit setImageX(true, index);
    });
    connect(ui->cBox_Image_Y, &QComboBox::currentIndexChanged, this, [=] () {
        auto index = ui->cBox_Image_Y->currentIndex();
        emit setImageX(false, index);
    });
    connect(ui->cBox_Left_X, &QComboBox::currentIndexChanged, this, [=] () {
        auto index = ui->cBox_Left_X->currentIndex();
        emit setLeftX(true, index);
    });
    connect(ui->cBox_Top_Y, &QComboBox::currentIndexChanged, this, [=] () {
        auto index = ui->cBox_Top_Y->currentIndex();
        emit setLeftX(false, index);
    });
    connect(ui->rBtn_Standard_CS, &QRadioButton::clicked, this, [=] () {
        emit setCoordSystemMode(0);
        ui->cBox_Image_X->setEnabled(false);
        ui->cBox_Image_Y->setEnabled(false);
        ui->cBox_Left_X->setEnabled(false);
        ui->cBox_Top_Y->setEnabled(false);
        ui->dSBox_UserX->setEnabled(false);
        ui->dSBox_UserY->setEnabled(false);
        ui->cBox_Relative->setEnabled(false);
        ui->btn_setToZero->setEnabled(false);
    });
    connect(ui->rBtn_Automatic, &QRadioButton::clicked, this, [=] () {
        emit setCoordSystemMode(1);
        ui->cBox_Image_X->setEnabled(true);
        ui->cBox_Image_Y->setEnabled(true);
        ui->cBox_Left_X->setEnabled(true);
        ui->cBox_Top_Y->setEnabled(true);
        ui->dSBox_UserX->setEnabled(false);
        ui->dSBox_UserY->setEnabled(false);
        ui->cBox_Relative->setEnabled(false);
        ui->btn_setToZero->setEnabled(false);
    });
    connect(ui->rBtn_UserDefined, &QRadioButton::clicked, this, [=] () {
        emit setCoordSystemMode(2);
        ui->cBox_Image_X->setEnabled(false);
        ui->cBox_Image_Y->setEnabled(false);
        ui->cBox_Left_X->setEnabled(false);
        ui->cBox_Top_Y->setEnabled(false);
        ui->dSBox_UserX->setEnabled(true);
        ui->dSBox_UserY->setEnabled(true);
        ui->cBox_Relative->setEnabled(true);
        ui->btn_setToZero->setEnabled(true);
    });
    connect(ui->dSBox_UserX, &QDoubleSpinBox::valueChanged, this, [=] () {
        auto xPos = ui->dSBox_UserX->value();
        auto yPos = ui->dSBox_UserY->value();
        auto bRelative = ui->cBox_Relative->isChecked();
        if(bRelative) {
            realXPos = realXPos + xPos;
        } else {
            realXPos = xPos;
            realYPos = yPos;
        }
        emit setUserDefinedPosition(realXPos, realYPos);
    });
    connect(ui->dSBox_UserY, &QDoubleSpinBox::valueChanged, this, [=] () {
        auto xPos = ui->dSBox_UserX->value();
        auto yPos = ui->dSBox_UserY->value();
        auto bRelative = ui->cBox_Relative->isChecked();
        if(bRelative) {
            realYPos = realYPos + yPos;
        } else {
            realXPos = xPos;
            realYPos = yPos;
        }
        emit setUserDefinedPosition(realXPos, realYPos);
    });
    connect(ui->btn_setToZero ,&QPushButton::clicked, this, [=] () {
        ui->dSBox_UserX->setValue(0);
        ui->dSBox_UserY->setValue(0);
    });
}

void BeamQuality_2D_View_Settings::setWindowTitleName(const QString& name) {
    setWindowTitle("BeamQuality -" + name);
}

void BeamQuality_2D_View_Settings::setStepByUnit(const QString& unit, double sizeX, double sizeY) {
    auto xStep = conversion(unit, sizeX);
    auto yStep = conversion(unit, sizeY);
    ui->dSBox_X->setSingleStep(xStep);
    ui->dSBox_Y->setSingleStep(yStep);
    ui->dSBox_D->setSingleStep(xStep);
    ui->dSBox_d->setSingleStep(yStep);
}

double BeamQuality_2D_View_Settings::conversion(QString unit, double size , int a) {
    const std::unordered_map<QString, double> conversionStep {
            {"px", a},
            {"um", size},
            {"mm", size / 1000.0},
            {"cm", size / 10000.0},
            {"in", size * 0.3937 / 10000.0}
    };
    const auto it = conversionStep.find(unit);
    return (it != conversionStep.end()) ? it->second : 1.0 / 1000000.0;
}

void BeamQuality_2D_View_Settings::setPositionSize(double dPositionX_px, double dPositionY_px, double dMajor_px, double dMinor_px, double dAzimuthAngle_px, int nShape) {
    changeUnable = true;
    ui->dSBox_X->setValue(dPositionX_px);
    ui->dSBox_Y->setValue(dPositionY_px);
    ui->dSBox_D->setValue(dMajor_px);
    ui->dSBox_d->setValue(dMinor_px);
    ui->dSBox_Phi->setValue(dAzimuthAngle_px);
    nShape == 0 ? ui->rBtn_Ellipse->setChecked(true) : ui->rBtn_Rectangle->setChecked(true);
    changeUnable = false;
}

void BeamQuality_2D_View_Settings::changePositionSizeUnit(const QString& unit) {
    ui->X_Position_Unit->setText(unit);
    ui->Y_Position_Unit->setText(unit);
    ui->D_Position_Unit->setText(unit);
    ui->d_Position_Unit->setText(unit);
}

void BeamQuality_2D_View_Settings::setPhi(double phi) {
    ui->dSBox_Phi->setValue(phi);
}

void BeamQuality_2D_View_Settings::setUserDefinedPositionX(double xPos) {
    ui->dSBox_UserX->setValue(xPos);
}

void BeamQuality_2D_View_Settings::setUserDefinedPositionY(double yPos) {
    ui->dSBox_UserY->setValue(yPos);
}

void BeamQuality_2D_View_Settings::initView() {
    ui->cBox_AdjustmentMethod->addItem("Position by Peak");
    ui->cBox_AdjustmentMethod->addItem("Position by Centroid");
    ui->cBox_AdjustmentMethod->addItem("Pos & Shape by 2nd Moments");
    ui->cBox_AdjustmentMethod->addItem("Pos & Shape by BeamWidth");
    ui->cBox_AdjustmentMethod->addItem("Pos & Shape by Horiz Projection");
    ui->cBox_AdjustmentMethod->addItem("Pos & Shape by Vert Projection");
    ui->cBox_AdjustmentMethod->setCurrentIndex(2);

    ui->cBox_Image_X->addItem("Image");
    ui->cBox_Image_X->addItem("AOI");
    ui->cBox_Image_X->setCurrentIndex(0);
    ui->cBox_Left_X->addItem("Left");
    ui->cBox_Left_X->addItem("Center");
    ui->cBox_Left_X->addItem("Right");
    ui->cBox_Left_X->setCurrentIndex(0);
    ui->cBox_Image_Y->addItem("Image");
    ui->cBox_Image_Y->addItem("AOI");
    ui->cBox_Image_Y->setCurrentIndex(0);
    ui->cBox_Top_Y->addItem("Top");
    ui->cBox_Top_Y->addItem("Center");
    ui->cBox_Top_Y->addItem("Bottom");
    ui->cBox_Top_Y->setCurrentIndex(0);

    systemModeGroup = new QButtonGroup(this);
    systemModeGroup->addButton(ui->rBtn_Standard_CS);
    systemModeGroup->addButton(ui->rBtn_Automatic);
    systemModeGroup->addButton(ui->rBtn_UserDefined);
}

BeamQuality_2D_View_Settings::~BeamQuality_2D_View_Settings() {
    delete ui;
}
